package com.imu.purse.modules.trade.service.impl;

import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.imu.constant.Constant;
import com.imu.core.base.BaseService;
import com.imu.enums.OrderTypeStatus;
import com.imu.enums.PStatus;
import com.imu.purse.modules.bitcoin.form.BitcoinForm;
import com.imu.purse.modules.trade.dao.FundMapper;
import com.imu.purse.modules.trade.dao.TradeInfoMapper;
import com.imu.purse.modules.trade.entity.FundEntity;
import com.imu.purse.modules.trade.entity.TradeInfoEntity;
import com.imu.purse.modules.trade.form.ScanTransForm;
import com.imu.purse.modules.trade.form.TransForm;
import com.imu.purse.modules.trade.service.TradeInfoService;
import com.xiaoleilu.hutool.bean.BeanUtil;
import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.log.Log;
import com.xiaoleilu.hutool.log.LogFactory;
import com.xiaoleilu.hutool.util.ArrayUtil;
import com.xiaoleilu.hutool.util.NumberUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 交易明细
 * @author sunhongwei
 * @email sunhongwei@jshijian.com
 * @date 2018-03-22 10:33:20
 * Copyright (c) 2017 武汉极时间科技有限公司 版权所有 
 * Jshijian aloha CO.,LTD. All Rights Reserved. 
 */
@Service
public class TradeInfoServiceImpl extends BaseService<TradeInfoEntity> implements TradeInfoService 
{
	private static Log log = LogFactory.get(TradeInfoServiceImpl.class);
	@Override
    @Transactional
    public int save(final TradeInfoEntity tradeInfo)
	{
		tradeInfo.setOrderCreate(new Date());
    	return super.insert(tradeInfo);
	}
	
	@Override
	@Transactional
    public int update(final TradeInfoEntity tradeInfo) 
    {
    	return mapper.updateByPrimaryKeySelective(tradeInfo);
    }
    
    @Override
	@Transactional
    public int saveUpdate(final TradeInfoEntity tradeInfo)
    {
    	int len = 0;
    	
    	if(1 > (len = this.update(tradeInfo)))
    	{
        	len = this.insert(tradeInfo);
    	}
    	
    	return len;
    }
    
 	@Override
	@Transactional
    public boolean delete(final String ...ids)
    {
    	if(ArrayUtil.isEmpty(ids)) return false;
    	
    	for (String id : ids) 
    	{
    		if(StrUtil.isBlank(id)) continue;
    		
    		if(NumberUtil.isNumber(id))
    		{
        		mapper.deleteByPrimaryKey(Long.valueOf(id));
    		}
		}
    	
    	return true;
    }
    
    @Override
    public TradeInfoEntity findById(final Long id)
    {
    	if(null == id) return null;
    	return mapper.findById(id);
    }
    
    @Override
    public List<TradeInfoEntity> queryList(final TradeInfoEntity tradeInfo)
    {
    	if (tradeInfo.getPage() != null && tradeInfo.getLimit() != null)
    	{
            PageHelper.startPage(tradeInfo.getPage(), tradeInfo.getLimit());
        }
    	
    	return mapper.findByPage(tradeInfo);
    }
    
    @Override
    @Transactional
	public void transferData(TransForm form) {
		List<Long> ids = Lists.newArrayList();
    	List<TradeInfoEntity> infoList = Lists.newArrayList();

    	Date nowDate = new Date();
    	//更新转出人金额
    	FundEntity fEntity = new FundEntity();
    	fEntity.setUserId(form.getPayUserId());
    	if(form.getOutFlag() && form.getRecUserId() == null){//属于外部转账(IMU转账到其他地方)
			//冻结转出人的金额
			fEntity.setFrozenMoney(form.getMoney().add(form.getFee()));
			fEntity.setTimeUpdate(nowDate);
			fundMapper.moFrozenMoney(fEntity);
			//交易信息
			TradeInfoEntity info = iniTradeInfoEntity(form,OrderTypeStatus.OUT.getType(),PStatus.Create.getType(),
					form.getPayUserId(),Constant.TRANSFER_OUT_ID,nowDate);
			infoList.add(info);
		}else if(form.getOutFlag() && form.getRecUserId() != null){//imu不同的核心钱包之间转账
			//冻结转出人的金额
			fEntity.setFrozenMoney(form.getMoney().add(form.getFee()));
			fEntity.setTimeUpdate(nowDate);
			fundMapper.moFrozenMoney(fEntity);
			//转出人
			//交易信息
			TradeInfoEntity info = iniTradeInfoEntity(form,OrderTypeStatus.OUT.getType(),PStatus.Create.getType(),
					form.getPayUserId(),form.getRecUserId(),nowDate);
			infoList.add(info);
			//接受人
			info = iniTradeInfoEntity(form,OrderTypeStatus.IN.getType(),PStatus.Create.getType(),
					form.getRecUserId(),form.getPayUserId(),nowDate);
			infoList.add(info);
		}else{//imu同一个核心钱包间转账
			//转出人
			fEntity.setMoney(form.getMoney().add(form.getFee()).multiply(new BigDecimal(-1)));
			fEntity.setTimeUpdate(nowDate);
			fundMapper.modMoneyByUId(fEntity);
			//接受人
			fEntity = new FundEntity();
			fEntity.setUserId(form.getRecUserId());
			fEntity.setMoney(form.getMoney());
			fEntity.setTimeUpdate(nowDate);
			fundMapper.modMoneyByUId(fEntity);
			//转出人
			//交易信息
			TradeInfoEntity info = iniTradeInfoEntity(form,OrderTypeStatus.OUT.getType(),PStatus.Finished.getType(),
					form.getPayUserId(),form.getRecUserId(),nowDate);
			infoList.add(info);
			//接受人
			info = iniTradeInfoEntity(form,OrderTypeStatus.IN.getType(),PStatus.Finished.getType(),
					form.getRecUserId(),form.getPayUserId(),nowDate);
			infoList.add(info);
		}

    	mapper.insertList(infoList);
		for(TradeInfoEntity info : infoList){
			ids.add(info.getId());
		}
		form.setIds(ids);
	}
    
    @Override
	@Transactional
	public void modBitData(List<BitcoinForm> fList) {
		// TODO Auto-generated method stub
		if(!CollectionUtils.isEmpty(fList)){
			for(BitcoinForm form : fList){
				//修改交易的信息
				int tNum = mapper.modByBitcoin(form);
				if(tNum == 0){//不存在，外部转入
					tNum = mapper.findCountByUTId(form);
					if(tNum == 0){//外部钱包转入到本钱包
						TradeInfoEntity tEntity = new TradeInfoEntity();
        				tEntity.setPayUserId(form.getUserId());
        				tEntity.setRecUserId(Constant.TRANSFER_OUT_ID);
        				tEntity.setOrderNo(DateUtil.format(new Date(), "yyyyMMddHHmmssSSS"));
        				tEntity.setOrderType(OrderTypeStatus.OUT.getType());//默认为转出
        				if(form.getCategory().equalsIgnoreCase(Constant.TRANSFER_RECEIVE)){
							tEntity.setOrderType(OrderTypeStatus.IN.getType());
						}
        				tEntity.setOrderState(PStatus.Finished.getType());
        				tEntity.setMoney(form.getAmount().abs());
        				tEntity.setOrderCreate(new Date());
        				tEntity.setTransId(form.getTransId());
        				mapper.insert(tEntity);
        				//更新当前用户
        				fundMapper.modNoByUId(form);
					}
				}else{//钱包内部互转或不同钱包间转账
					//fee默认为0
					if(Constant.TRANSFER_SEND.equalsIgnoreCase(form.getCategory())){//转出者
						fundMapper.modByUId(form);
					}else{//接受者
						fundMapper.modNoByUId(form);
					}
				}
			}
		}
	}
	/**
	 * 构建交易信息
	 * @param form
	 * @param orderType
	 * @param orderState
	 * @param fromUId
	 * @param toUId
	 * @param nowDate
	 * @return
	 */
	private TradeInfoEntity iniTradeInfoEntity(TransForm form,Integer orderType, Integer orderState,Long fromUId,
											   Long toUId, Date nowDate){
		TradeInfoEntity info = new TradeInfoEntity();
		BeanUtil.copyProperties(form, info);
		info.setPayUserId(fromUId);
		info.setRecUserId(toUId);
		if(orderType == OrderTypeStatus.IN.getType()){//转入
			info.setRecAddr(form.getPayAddr());
			info.setRecPhone(form.getPayPhone());
		}
		info.setOrderType(orderType);
		info.setOrderState(orderState);
		info.setTransId(form.getTransId());
		info.setOrderCreate(nowDate);
		return info;
	}

	@Override
    public List<TradeInfoEntity> queryLists(final TradeInfoEntity tradeInfo)
    {
    	if (tradeInfo.getPage() != null && tradeInfo.getLimit() != null)
    	{
            PageHelper.startPage(tradeInfo.getPage(), tradeInfo.getLimit());
        }
    	
    	return mapper.findByPages(tradeInfo);
    }

	@Override
	@Transactional
	public int transOutDate(final TransForm form){
		return mapper.upTIdById(form);
	}

	@Override
	@Transactional
	public void scanTrans(ScanTransForm form,Map<String,BigDecimal> moneyMap) {
		List<Long> ids = Lists.newArrayList();
		List<TradeInfoEntity> infoList = Lists.newArrayList();

		Date nowDate = new Date();
		//更新转出人金额
		FundEntity fEntity = new FundEntity();
		fEntity.setUserId(form.getPayUserId());
		if(form.getOutFlag()){//外部转账
			//冻结转出人的金额
			fEntity.setFrozenMoney(form.getMoney().add(form.getFee()));
			fEntity.setTimeUpdate(nowDate);
			fundMapper.moFrozenMoney(fEntity);
			//转出人
			//交易信息
			TradeInfoEntity info = iniTradeInfoEntity(form,OrderTypeStatus.OUT.getType(),PStatus.Create.getType(),
					form.getPayUserId(),form.getRecUserId(),nowDate);
			info.setSmoney(moneyMap.get("payMoney"));
			info.setEmoney(moneyMap.get("payMoney").subtract(form.getMoney()).subtract(form.getFee()));
			infoList.add(info);

		}else{
			Integer orderState = PStatus.Finished.getType();//默认为完成
			//转出人
			fEntity.setMoney(form.getMoney().add(form.getFee()).multiply(new BigDecimal(-1)));
			fEntity.setTimeUpdate(nowDate);
			fEntity.setYtfType(form.getYtfType());
			fundMapper.updateMoneyByUIdAndYtype(fEntity);
			//接受人
			fEntity = new FundEntity();
			fEntity.setYtfType(form.getYtfType());
			fEntity.setUserId(form.getRecUserId());
			fEntity.setMoney(form.getMoney());
			fEntity.setTimeUpdate(nowDate);
			fundMapper.updateMoneyByUIdAndYtype(fEntity);
			//交易信息 转出人
			TradeInfoEntity info = iniTradeInfoEntity(form,OrderTypeStatus.OUT.getType(),orderState,
					form.getPayUserId(),form.getRecUserId(),nowDate);
			info.setSmoney(moneyMap.get("payMoney"));
			info.setEmoney(moneyMap.get("payMoney").subtract(form.getMoney()).subtract(form.getFee()));
			infoList.add(info);
			//接受人
			info = iniTradeInfoEntity(form,OrderTypeStatus.IN.getType(),orderState,
					form.getRecUserId(),form.getPayUserId(),nowDate);
			info.setSmoney(moneyMap.get("recMoney"));
			info.setEmoney(moneyMap.get("recMoney").add(form.getMoney()));
			infoList.add(info);
		}

		mapper.insertList(infoList);
		for(TradeInfoEntity info : infoList){
			ids.add(info.getId());
		}
		form.setIds(ids);
	}

	private TradeInfoEntity iniTradeInfoEntity(ScanTransForm form,Integer orderType, Integer orderState,Long fromUId,
											   Long toUId, Date nowDate){
		TradeInfoEntity info = new TradeInfoEntity();
		BeanUtil.copyProperties(form, info);
		info.setPayUserId(fromUId);
		info.setRecUserId(toUId);
		if(orderType == OrderTypeStatus.IN.getType()){//转入
			info.setRecAddr(form.getPayAddr());
			info.setRecPhone(form.getPayPhone());
		}
		info.setOrderType(orderType);
		info.setOrderState(orderState);
		info.setTransId(form.getTransId());
		info.setOrderCreate(nowDate);
		return info;
	}

	public BigDecimal getMoneyByUIdAndDay(Long userId,Date nowDate){
		return mapper.getMoneyByUIdAndDay(userId,nowDate);
	}

	@Autowired
	private TradeInfoMapper mapper;
	
	@Autowired
	private FundMapper fundMapper;
}
